package com.meme.io.editor;

import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Attr;
import org.w3c.dom.Text;

import com.meme.editor.EntityObject;
import com.meme.editor.level.*;
import com.meme.editor.level.define.*;

import com.meme.editor.property.PropertyGroupSet;
import com.meme.editor.property.Property;

import com.meme.util.FileUtil;
import com.meme.util.XmlUtil;

public class LevelXmlFileWriter 
{
	static Logger logger = Logger.getLogger (LevelXmlFileWriter.class);

	String mLevelFilename;
	
	public Document writeToXmlDocument (LevelFile levelFile)
	{
		Document document = XmlUtil.createNewDocument();
		
		// ...
		writeLevelFile (document, levelFile);
		
		return document;
	}
	
	public void writeToFile (LevelFile levelFile, String filename)
	{
		if ( ! filename.endsWith("." + LevelFile.getFileExtension()) )
			filename = filename + "." + LevelFile.getFileExtension();
		
		mLevelFilename = filename;
		
		Document document = writeToXmlDocument (levelFile);

		XmlUtil.writeXmlFile(document, filename);
		
		levelFile.setHostFilename (filename);
		levelFile.commitModifications ();
	}
	
	
//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------

	
	void writeLevelFile (Document document, LevelFile levelFile)
	{
		Element levelElement = document.createElement("Level");
		document.appendChild(levelElement);

		levelElement.setAttribute("version", "1.0");
			

		// properties
		{
			// property group
			writePropertyGroupSet (document, levelElement, levelFile.getPublicProperties());

			// special handling
			Element propertiesElement = XmlUtil.getChildElementByName (levelElement, "Properties");
			Element[] groupElements = XmlUtil.getChildElementsByName (propertiesElement, "PropertyGroup");
			for (Element groupElement : groupElements)
			{
				if (groupElement.getAttribute("name").equals (LevelFile.GroupName_LevelGroup) )
				{
					Element[] propertyElements = XmlUtil.getChildElementsByName (groupElement, "Property");
					for (Element propertyElement : propertyElements)
					{
						if (propertyElement.getAttribute("name").equals (LevelFile.PropertyName_DefineFile) )
						{
							String oldValue = propertyElement.getAttribute("value");
							if (oldValue.length() > 0)
							{
								propertyElement.setAttribute("value", FileUtil.getRelativePathFilename(oldValue, mLevelFilename));
							}
						}
					}
				}
			}
		}
		
		// actors
		{
			Element actorsElement = document.createElement ("Actors");
			levelElement.appendChild (actorsElement);
			
			for (EntityObject entity : levelFile.getActorList())
			{
				Actor actor = (Actor) entity;
				writeActor (document, actorsElement, actor);
			}
		}
		
	}
	
	
	void writePropertyGroupSet (Document document, Element parentElement, PropertyGroupSet propertyGroupSet)
	{
		Element propertiesElement = document.createElement ("Properties");
		parentElement.appendChild (propertiesElement);
		
		for ( int groupID = 0; groupID < propertyGroupSet.getPropertyGroupsCont(); ++ groupID )
		{
			String groupName = propertyGroupSet.getPropertyGroupName (groupID);
			Element groupElement = document.createElement ("PropertyGroup");
			groupElement.setAttribute ("name", groupName);
			propertiesElement.appendChild (groupElement);
			
			for ( int propertyID = 0; propertyID < propertyGroupSet.getPropertiesCountInGroup (groupID); ++ propertyID )
			{
				Property property = propertyGroupSet.getPropertyInGroup (groupID, propertyID);
				writeProperty (document, groupElement, property);
			}
		}
	}
	
	void writeProperty (Document document, Element parentElement, Property property)
	{
		Element propertyElement = document.createElement ("Property");
		parentElement.appendChild (propertyElement);
		
		propertyElement.setAttribute ("name", property.getName ());
		propertyElement.setAttribute ("value", property.getValueAsString());
	}
	
	void writeActor (Document document, Element parentElement, Actor actor)
	{
		Element actorElement = document.createElement ("Actor");
		actorElement.setAttribute ("template", actor.getActorTemplate().getName());
		parentElement.appendChild (actorElement);
	
		// properties
		writePropertyGroupSet (document, actorElement, actor.getPublicProperties());
		
		// appearances
		Element appearancesElement = document.createElement ("Appearances");
		actorElement.appendChild (appearancesElement);
		for (Appearance appearance : actor.getAppearanceList())
		{
			writeAppearance (document, appearancesElement, appearance);
		}
	}
	
	void writeAppearance (Document document, Element parentElement, Appearance appearance)
	{
		Element appearanceElement = document.createElement ("Appearance");
		parentElement.appendChild (appearanceElement);
		
		// properties
		writePropertyGroupSet (document, appearanceElement, appearance.getPublicProperties());
		
	}

	
}
